(-) describe & visualize relationship between variables (multivariate) (-) correlation plots (-) gather interesting observations for further investigation (-) gather possible new features for extraction
insights
- we can see the waves in the frequency of the events, but it seems that the duration is stable / constant, except for Los Angeles; may be the events are a little longer over the years on average
- Snow comes in seasons in New York and Seattle of course, but cold seem to increase in New York and Los Angeles since 2019 and not stick to winter season; Fog is mostly in Los Angeles and also increasing since 2019, Rain is present is all cities all the year, Seattle seems to have waves / seasons of Rain, and Los Angeles hast most year almost no Rain with spikes, funny is that in overall plot per city the snow seasons in New York did not really show, but in Seattle they really do, maybe since they sync with rain waves
- Severe events seem to increase since 2019, which might be Fog in Los Angeles
- can’t quite find the reason why there is so much reporting at specific fixed minutes, might be automated but trigger is unknown, but there is an interesting pattern here, might be because of recording method
- Houston has constant Rain and less Fog in Summer; Los Angeles has no Rain in Summer, but constant Fog and also Cold; New York has constant Rain and Fog, Snow in Winter, Cold also all Year; Seattle has less Rain in Summer, Fog and Snow in Winter
- Fog seems to have starting hours (and end): Houston 9 - 12 to 13 - 14, Los Angeles 14 - 16 to 15 - 19, New York 12 - 14 to 14 - 16, Seattle 13 - 16 to 15 - 18 all others are constant across hours of day
- Houston stable over years, Los Angeles increased Cold and Fog, New York mostly stable, but jump 2019 in Cold, Seattle little increase in Fog and decrease in Snow
(!) compare 4 big cities which are all close to the coast but vary in significantly in longitude and latitude
head(weather)
summary(weather)
EventId Type Severity StartTime EndTime TimeZone LocationLat LocationLng
Length:12226 Cold : 365 Heavy : 439 Min. :2016-01-01 08:47:00 Min. :2016-01-01 09:47:00 US/Central:2900 Min. :29.98 Min. :-122.31
Class :character Fog :2920 Light :6792 1st Qu.:2017-04-08 08:59:45 1st Qu.:2017-04-08 11:06:30 US/Eastern:3656 1st Qu.:34.02 1st Qu.:-122.31
Mode :character Hail : 6 Moderate:3428 Median :2018-09-27 02:42:30 Median :2018-09-27 03:02:30 US/Pacific:5670 Median :40.78 Median : -95.36
Precipitation: 139 Other : 6 Mean :2018-08-09 22:18:52 Mean :2018-08-09 23:49:14 Mean :38.70 Mean :-100.68
Rain :8296 Severe :1422 3rd Qu.:2019-11-24 10:37:30 3rd Qu.:2019-11-24 12:37:30 3rd Qu.:47.44 3rd Qu.: -73.97
Snow : 494 UNK : 139 Max. :2020-12-31 23:22:00 Max. :2020-12-31 23:53:00 Max. :47.44 Max. : -73.97
Storm : 6
City Duration
Houston :2900 Length:12226
Los Angeles:2378 Class :difftime
New York :3656 Mode :numeric
Seattle :3292
| multivariate Duration over StartTime |
we can see the waves in the frequency of the events, but it seems that the duration is stable / constant, except for Los Angeles; may be the events are a little longer over the years on average
-> is there another plot for seeing the duration over time and verifying it to be mostly constant?
time_duration_plot_point <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = StartTime, y = as.numeric(Duration), col = fct_infreq(City))) +
geom_point(alpha = 0.2, size = 0.5) +
geom_smooth() +
theme_minimal() +
facet_grid(vars(City)) +
ggtitle("Duration over StartTime")
ggplotly(time_duration_plot_point)
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
| multivariate Type over StartTime |
Snow comes in seasons in New York and Seattle of course, but cold seem to increase in New York and Los Angeles since 2019 and not stick to winter season; Fog is mostly in Los Angeles and also increasing since 2019, Rain is present is all cities all the year, Seattle seems to have waves / seasons of Rain, and Los Angeles hast most year almost no Rain with spikes, funny is that in overall plot per city the snow seasons in New York did not really show, but in Seattle they really do, maybe since they sync with rain waves
time_type_plot_point <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = StartTime, y = fct_infreq(Type), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
# facet_grid(vars(City)) +
ggtitle("Type over StartTime")
ggplotly(time_type_plot_point)
time_type_plot_freq <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = StartTime, col = fct_infreq(City))) +
geom_freqpoly(alpha = 0.8, bins = 30) +
theme_minimal() +
facet_grid(vars(fct_infreq(Type))) +
ggtitle("Type over StartTime")
ggplotly(time_type_plot_freq)
| multivariate Severity over StartTime |
Severe events seem to increase since 2019, which might be Fog in Los Angeles
time_severity_plot_point <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = StartTime, y = fct_infreq(Severity), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
# facet_grid(vars(City)) +
ggtitle("Severity over StartTime")
ggplotly(time_severity_plot_point)
time_severity_plot_freq <- weather %>%
filter(as.numeric(Duration) < 600) %>%
ggplot(aes(x = StartTime, col = fct_infreq(City))) +
geom_freqpoly(alpha = 0.8, bins = 30) +
theme_minimal() +
facet_grid(vars(fct_infreq(Severity))) +
ggtitle("Severity over StartTime")
ggplotly(time_severity_plot_freq)
| multivariate Duration over Minute |
can’t quite find the reason why there is so much reporting at specific fixed minutes, might be automated but trigger is unknown, but there is an interesting pattern here, might be because of recording method
minute_severity_plot_freq <- weather %>%
filter(as.numeric(Duration) < 600) %>%
mutate(minute = minute(StartTime)) %>%
ggplot(aes(x = minute, y = as.numeric(Duration), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
theme_minimal() +
ggtitle("Severity over Minute")
ggplotly(minute_severity_plot_freq)
| multivariate Type over Month |
Houston has constant Rain and less Fog in Summer; Los Angeles has no Rain in Summer, but constant Fog and also Cold; New York has constant Rain and Fog, Snow in Winter, Cold also all Year; Seattle has less Rain in Summer, Fog and Snow in Winter
-> I guess there is a better plot for this, but its good for now
month_type_plot_freq <- weather %>%
mutate(month = month(StartTime, label = TRUE)) %>%
ggplot(aes(x = month, y = fct_infreq(Type), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over Month")
ggplotly(month_type_plot_freq)
| multivariate Type over Hour |
Fog seems to have starting hours (and end): Houston 9 - 12 to 13 - 14, Los Angeles 14 - 16 to 15 - 19, New York 12 - 14 to 14 - 16, Seattle 13 - 16 to 15 - 18 Rain in Houston is also more often starting in the second half of the day all others are constant across hours of day
-> sync for local time zone to understand morning and evening time dependend events
hour_type_plot_freq <- weather %>%
mutate(hour = hour(StartTime)) %>%
ggplot(aes(x = hour, y = fct_infreq(Type), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over Hour")
hour_type_plot_bar <- weather %>%
mutate(hour = hour(StartTime)) %>%
ggplot(aes(x = hour, fill = fct_infreq(Type))) +
geom_bar(position = position_dodge(preserve = "single")) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over Start Hour")
ggplotly(hour_type_plot_freq)
ggplotly(hour_type_plot_bar)
position_dodge requires non-overlapping x intervalsposition_dodge requires non-overlapping x intervals
hour_type_plot_freq <- weather %>%
mutate(hour = hour(EndTime)) %>%
ggplot(aes(x = hour, y = fct_infreq(Type), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over Hour")
hour_type_plot_bar <- weather %>%
mutate(hour = hour(EndTime)) %>%
ggplot(aes(x = hour, fill = fct_infreq(Type))) +
geom_bar(position = position_dodge(preserve = "single")) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over End Hour")
ggplotly(hour_type_plot_freq)
ggplotly(hour_type_plot_bar)
position_dodge requires non-overlapping x intervalsposition_dodge requires non-overlapping x intervalsposition_dodge requires non-overlapping x intervals
| multivariate Type over Year |
Houston stable over years, Los Angeles increased Cold and Fog, New York mostly stable, but jump 2019 in Cold, Seattle little increase in Fog and decrease in Snow
year_type_plot_freq <- weather %>%
mutate(year = year(StartTime)) %>%
ggplot(aes(x = year, y = fct_infreq(Type), col = fct_infreq(City))) +
geom_jitter(alpha = 0.2, size = 0.5) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over Year")
ggplotly(year_type_plot_freq)
year_type_plot_freq <- weather %>%
mutate(year = year(StartTime)) %>%
ggplot(aes(x = year, fill = fct_infreq(Type))) +
geom_bar(position = position_dodge(preserve = "single")) +
facet_grid(vars(City)) +
theme_minimal() +
ggtitle("Type over Year")
ggplotly(year_type_plot_freq)
position_dodge requires non-overlapping x intervals
LS0tDQp0aXRsZTogImRlc2NyaWJlIGFuZCB2aXN1YWxpemUgb2YgVVMgd2VhdGhlciBldmVudCBkYXRhIg0Kc3VidGl0bGU6ICJjaXR5IHNlbGVjdGlvbiAtIG11bHRpdmFyaWF0ZSBmb3IgdGltZSB2YXJpYWJsZXMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQotLS0NCnB1cnBvc2Ugb2Ygbm90ZWJvb2sNCi0tLQ0KDQogICgtKSBkZXNjcmliZSAmIHZpc3VhbGl6ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB2YXJpYWJsZXMgKG11bHRpdmFyaWF0ZSkNCiAgKC0pIGNvcnJlbGF0aW9uIHBsb3RzIA0KICAoLSkgZ2F0aGVyIGludGVyZXN0aW5nIG9ic2VydmF0aW9ucyBmb3IgZnVydGhlciBpbnZlc3RpZ2F0aW9uDQogICgtKSBnYXRoZXIgcG9zc2libGUgbmV3IGZlYXR1cmVzIGZvciBleHRyYWN0aW9uDQogIA0KdG9kb3M6DQogICgtKSAuLi4NCg0KLS0tDQppbmZvcm1hdGlvbg0KLS0tDQpodHRwczovL3d3dy5rYWdnbGUuY29tL3NvYmhhbm1vb3NhdmkvdXMtd2VhdGhlci1ldmVudHMNCmh0dHBzOi8vc21vb3Nhdmkub3JnL2RhdGFzZXRzL2xzdHcNCg0KTW9vc2F2aSwgU29iaGFuLCBNb2hhbW1hZCBIb3NzZWluIFNhbWF2YXRpYW4sIEFybmFiIE5hbmRpLCBTcmluaXZhc2FuIFBhcnRoYXNhcmF0aHksIGFuZCBSYWppdiBSYW1uYXRoLiDigJxTaG9ydCBhbmQgTG9uZy10ZXJtIFBhdHRlcm4gRGlzY292ZXJ5IE92ZXIgTGFyZ2UtU2NhbGUgR2VvLVNwYXRpb3RlbXBvcmFsIERhdGEu4oCdIEluIFByb2NlZWRpbmdzIG9mIHRoZSAyNXRoIEFDTSBTSUdLREQgSW50ZXJuYXRpb25hbCBDb25mZXJlbmNlIG9uIEtub3dsZWRnZSBEaXNjb3ZlcnkgJiBEYXRhIE1pbmluZywgQUNNLCAyMDE5Lg0KDQpXZWF0aGVyIGV2ZW50IGlzIGEgc3BhdGlvdGVtcG9yYWwgZW50aXR5LCB3aGVyZSBzdWNoIGFuIGVudGl0eSBpcyBhc3NvY2lhdGVkIHdpdGggbG9jYXRpb24gYW5kIHRpbWUuIEZvbGxvd2luZyBpcyB0aGUgZGVzY3JpcHRpb24gb2YgYXZhaWxhYmxlIHdlYXRoZXIgZXZlbnQgdHlwZXM6DQoNCiAgICBTZXZlcmUtQ29sZDogVGhlIGNhc2Ugb2YgaGF2aW5nIGV4dHJlbWVseSBsb3cgdGVtcGVyYXR1cmUsIHdpdGggdGVtcGVyYXR1cmUgYmVsb3cgLTIzLjcgZGVncmVlcyBvZiBDZWxzaXVzLg0KICAgIEZvZzogVGhlIGNhc2Ugd2hlcmUgdGhlcmUgaXMgbG93IHZpc2liaWxpdHkgY29uZGl0aW9uIGFzIGEgcmVzdWx0IG9mIGZvZyBvciBoYXplLg0KICAgIEhhaWw6IFRoZSBjYXNlIG9mIGhhdmluZyBzb2xpZCBwcmVjaXBpdGF0aW9uIGluY2x1ZGluZyBpY2UgcGVsbGV0cyBhbmQgaGFpbC4NCiAgICBSYWluOiBUaGUgY2FzZSBvZiBoYXZpbmcgcmFpbiwgcmFuZ2luZyBmcm9tIGxpZ2h0IHRvIGhlYXZ5Lg0KICAgIFNub3c6IFRoZSBjYXNlIG9mIGhhdmluZyBzbm93LCByYW5naW5nIGZyb20gbGlnaHQgdG8gaGVhdnkuDQogICAgU3Rvcm06IFRoZSBleHRyZW1lbHkgd2luZHkgY29uZGl0aW9uLCB3aGVyZSB0aGUgd2luZCBzcGVlZCBpcyBhdCBsZWFzdCA2MCBrbS9oLg0KICAgIE90aGVyIFByZWNpcGl0YXRpb246IEFueSBvdGhlciB0eXBlIG9mIHByZWNpcGl0YXRpb24gd2hpY2ggY2Fubm90IGJlIGFzc2lnbmVkIHRvIHByZXZpb3VzbHkgZGVzY3JpYmVkIGV2ZW50IHR5cGVzLg0KDQpUaGUgd2VhdGhlciBkYXRhIGlzIHByb3ZpZGVkIGluIHRlcm1zIG9mIGEgQ1NWIGZpbGUgd2l0aCB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6DQogICAgICBBdHRyaWJ1dGUJICAgICAgICBEZXNjcmlwdGlvbgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdWxsYWJsZQ0KMQkgICAgRXZlbnRJZAkgICAgICAgICAgVGhpcyBpcyB0aGUgaWRlbnRpZmllciBvZiBhIHJlY29yZAkgICAgICAgICAgICAgICAgICAgICAgICBObw0KMiAgIAlUeXBlCSAgICAgICAgICAgIFRoZSB0eXBlIG9mIGFuIGV2ZW50OyBleGFtcGxlcyBhcmUgcmFpbiBhbmQgc25vdy4JICAgICAgICAgIE5vDQozCSAgICBTZXZlcml0eQkgICAgICAgIFRoZSBzZXZlcml0eSBvZiBhbiBldmVudCwgd2hlcmV2ZXIgYXBwbGljYWJsZS4gICAgICAgIAkgICAgWWVzDQo0CSAgICBTdGFydFRpbWUgKFVUQykJICBUaGUgc3RhcnQgdGltZSBvZiBhbiBldmVudCBpbiBVVEMgdGltZSB6b25lLiAgICAgICAgICAJICAgIE5vDQo1CSAgICBFbmRUaW1lIChVVEMpCSAgICBUaGUgZW5kIHRpbWUgb2YgYW4gZXZlbnQgaW4gVVRDIHRpbWUgem9uZS4JICAgICAgICAgICAgICAgIE5vDQo2CSAgICBUaW1lWm9uZQkgICAgICAgIFRoZSBVUy1iYXNlZCB0aW1lem9uZSBiYXNlZCBvbiB0aGUgbG9jYXRpb24gb2YgYW4gZXZlbnQgICAgIE5vDQogICAgICAgICAgICAgICAgICAgICAgICAoZWFzdGVybiwgY2VudHJhbCwgbW91bnRhaW4sIGFuZCBwYWNpZmljKS4JDQo3CSAgICBMb2NhdGlvbkxhdAkgICAgICBUaGUgbGF0aXR1ZGUgaW4gR1BTIGNvb3JkaW5hdGUuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjggICAJTG9jYXRpb25MbmcJICAgICAgVGhlIGxvbmdpdHVkZSBpbiBHUFMgY29vcmRpbmF0ZS4JICAgICAgICAgICAgICAgICAgICAgICAgICBZZXMNCjkJICAgIEFpcnBvcnRDb2RlCSAgICAgIFRoZSBhaXJwb3J0IHN0YXRpb24gdGhhdCBhIHdlYXRoZXIgZXZlbnQgaXMgcmVwb3J0ZWQgZnJvbS4JWWVzDQoxMAkgIENpdHkJICAgICAgICAgICAgVGhlIGNpdHkgaW4gYWRkcmVzcyByZWNvcmQuCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoxMQkgIENvdW50eQkgICAgICAgICAgVGhlIGNvdW50eSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoxMgkgIFN0YXRlCSAgICAgICAgICAgIFRoZSBzdGF0ZSBpbiBhZGRyZXNzIHJlY29yZC4JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoxMwkgIFppcENvZGUJICAgICAgICAgIFRoZSB6aXBjb2RlIGluIGFkZHJlc3MgcmVjb3JkLgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgWWVzDQoNCi0tLQ0KaW5zaWdodHMgDQotLS0NCiAgDQogIChpKSB3ZSBjYW4gc2VlIHRoZSB3YXZlcyBpbiB0aGUgZnJlcXVlbmN5IG9mIHRoZSBldmVudHMsIGJ1dCBpdCBzZWVtcyB0aGF0IHRoZSBkdXJhdGlvbiBpcyBzdGFibGUgLyBjb25zdGFudCwgZXhjZXB0IGZvciBMb3MgQW5nZWxlczsNCiAgICAgIG1heSBiZSB0aGUgZXZlbnRzIGFyZSBhIGxpdHRsZSBsb25nZXIgb3ZlciB0aGUgeWVhcnMgb24gYXZlcmFnZQ0KICAoaSkgU25vdyBjb21lcyBpbiBzZWFzb25zIGluIE5ldyBZb3JrIGFuZCBTZWF0dGxlIG9mIGNvdXJzZSwgYnV0IGNvbGQgc2VlbSB0byBpbmNyZWFzZSBpbiBOZXcgWW9yayBhbmQgTG9zIEFuZ2VsZXMgc2luY2UgMjAxOSBhbmQgbm90IHN0aWNrIHRvIHdpbnRlciBzZWFzb247DQogICAgICBGb2cgaXMgbW9zdGx5IGluIExvcyBBbmdlbGVzIGFuZCBhbHNvIGluY3JlYXNpbmcgc2luY2UgMjAxOSwgDQogICAgICBSYWluIGlzIHByZXNlbnQgaXMgYWxsIGNpdGllcyBhbGwgdGhlIHllYXIsIFNlYXR0bGUgc2VlbXMgdG8gaGF2ZSB3YXZlcyAvIHNlYXNvbnMgb2YgUmFpbiwgYW5kIExvcyBBbmdlbGVzIGhhc3QgbW9zdCB5ZWFyIGFsbW9zdCBubyBSYWluIHdpdGggc3Bpa2VzLCANCiAgICAgIGZ1bm55IGlzIHRoYXQgaW4gb3ZlcmFsbCBwbG90IHBlciBjaXR5IHRoZSBzbm93IHNlYXNvbnMgaW4gTmV3IFlvcmsgZGlkIG5vdCByZWFsbHkgc2hvdywgYnV0IGluIFNlYXR0bGUgdGhleSByZWFsbHkgZG8sIG1heWJlIHNpbmNlIHRoZXkgc3luYyB3aXRoIHJhaW4gd2F2ZXMNCiAgKGkpIFNldmVyZSBldmVudHMgc2VlbSB0byBpbmNyZWFzZSBzaW5jZSAyMDE5LCB3aGljaCBtaWdodCBiZSBGb2cgaW4gTG9zIEFuZ2VsZXMNCiAgKGkpIGNhbid0IHF1aXRlIGZpbmQgdGhlIHJlYXNvbiB3aHkgdGhlcmUgaXMgc28gbXVjaCByZXBvcnRpbmcgYXQgc3BlY2lmaWMgZml4ZWQgbWludXRlcywgbWlnaHQgYmUgYXV0b21hdGVkIGJ1dCB0cmlnZ2VyIGlzIHVua25vd24sIA0KICAgICAgYnV0IHRoZXJlIGlzIGFuIGludGVyZXN0aW5nIHBhdHRlcm4gaGVyZSwgbWlnaHQgYmUgYmVjYXVzZSBvZiByZWNvcmRpbmcgbWV0aG9kDQogIChpKSBIb3VzdG9uIGhhcyBjb25zdGFudCBSYWluIGFuZCBsZXNzIEZvZyBpbiBTdW1tZXI7IExvcyBBbmdlbGVzIGhhcyBubyBSYWluIGluIFN1bW1lciwgYnV0IGNvbnN0YW50IEZvZyBhbmQgYWxzbyBDb2xkOyBOZXcgWW9yayBoYXMgY29uc3RhbnQgUmFpbiBhbmQgRm9nLCBTbm93IGluIFdpbnRlciwgQ29sZCAgICAgICAgICBhbHNvIGFsbCBZZWFyOyBTZWF0dGxlIGhhcyBsZXNzIFJhaW4gaW4gU3VtbWVyLCBGb2cgYW5kIFNub3cgaW4gV2ludGVyDQogIChpKSBGb2cgc2VlbXMgdG8gaGF2ZSBzdGFydGluZyBob3VycyAoYW5kIGVuZCk6IEhvdXN0b24gOSAtIDEyIHRvIDEzIC0gMTQsIExvcyBBbmdlbGVzIDE0IC0gMTYgdG8gMTUgLSAxOSwgTmV3IFlvcmsgMTIgLSAxNCB0byAxNCAtIDE2LCBTZWF0dGxlIDEzIC0gMTYgdG8gMTUgLSAxOA0KICAgICAgYWxsIG90aGVycyBhcmUgY29uc3RhbnQgYWNyb3NzIGhvdXJzIG9mIGRheQ0KICAoaSkgSG91c3RvbiBzdGFibGUgb3ZlciB5ZWFycywgTG9zIEFuZ2VsZXMgaW5jcmVhc2VkIENvbGQgYW5kIEZvZywgTmV3IFlvcmsgbW9zdGx5IHN0YWJsZSwgYnV0IGp1bXAgMjAxOSBpbiBDb2xkLCBTZWF0dGxlIGxpdHRsZSBpbmNyZWFzZSBpbiBGb2cgYW5kIGRlY3JlYXNlIGluIFNub3cNCg0KLS0tDQpzdG9yaWVzDQotLS0NCg0KICAoISkgY29tcGFyZSA0IGJpZyBjaXRpZXMgd2hpY2ggYXJlIGFsbCBjbG9zZSB0byB0aGUgY29hc3QgYnV0IHZhcnkgaW4gc2lnbmlmaWNhbnRseSBpbiBsb25naXR1ZGUgYW5kIGxhdGl0dWRlDQoNCi0tLQ0KbG9hZCBwYWNrYWdlcw0KLS0tDQpgYGB7ciBsb2FkIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpICMgdGlkeSBkYXRhIGZyYW1lDQpsaWJyYXJ5KGdndGhlbWVzKSAjIGZvciBleHRyYSBwbG90IHRoZW1lcw0KbGlicmFyeShwbG90bHkpICMgbWFrZSBnZ3Bsb3RzIGludGVyYWN0aXZlDQpsaWJyYXJ5KGx1YnJpZGF0ZSkgIyBmdW5jdGlvbnMgdG8gd29yayB3aXRoIGRhdGUtdGltZXMgYW5kIHRpbWUtc3BhbnMNCmxpYnJhcnkoY29ycnBsb3QpICMgY29ycmVsYXRpb24gcGxvdHMNCmxpYnJhcnkoZ2dtb3NhaWMpICMgZ2VvbV9tb3NhaWMoKSBtb3NhaWMgcGxvdHMgZm9yIGNhdGVnb3JpY2FsIGRhdGENCmBgYA0KDQotLS0NCm92ZXJ2aWV3DQotLS0NCmBgYHtyfQ0KaGVhZCh3ZWF0aGVyKQ0KYGBgDQpgYGB7cn0NCnN1bW1hcnkod2VhdGhlcikNCmBgYA0KDQotLS0NCm11bHRpdmFyaWF0ZSBEdXJhdGlvbiBvdmVyIFN0YXJ0VGltZQ0KLS0tDQp3ZSBjYW4gc2VlIHRoZSB3YXZlcyBpbiB0aGUgZnJlcXVlbmN5IG9mIHRoZSBldmVudHMsIGJ1dCBpdCBzZWVtcyB0aGF0IHRoZSBkdXJhdGlvbiBpcyBzdGFibGUgLyBjb25zdGFudCwgZXhjZXB0IGZvciBMb3MgQW5nZWxlczsNCm1heSBiZSB0aGUgZXZlbnRzIGFyZSBhIGxpdHRsZSBsb25nZXIgb3ZlciB0aGUgeWVhcnMgb24gYXZlcmFnZQ0KDQotPiBpcyB0aGVyZSBhbm90aGVyIHBsb3QgZm9yIHNlZWluZyB0aGUgZHVyYXRpb24gb3ZlciB0aW1lIGFuZCB2ZXJpZnlpbmcgaXQgdG8gYmUgbW9zdGx5IGNvbnN0YW50Pw0KDQpgYGB7cn0NCnRpbWVfZHVyYXRpb25fcGxvdF9wb2ludCA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBTdGFydFRpbWUsIHkgPSBhcy5udW1lcmljKER1cmF0aW9uKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgZ2VvbV9zbW9vdGgoKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICBnZ3RpdGxlKCJEdXJhdGlvbiBvdmVyIFN0YXJ0VGltZSIpDQoNCmdncGxvdGx5KHRpbWVfZHVyYXRpb25fcGxvdF9wb2ludCkNCmBgYA0KDQotLS0NCm11bHRpdmFyaWF0ZSBUeXBlIG92ZXIgU3RhcnRUaW1lDQotLS0NClNub3cgY29tZXMgaW4gc2Vhc29ucyBpbiBOZXcgWW9yayBhbmQgU2VhdHRsZSBvZiBjb3Vyc2UsIGJ1dCBjb2xkIHNlZW0gdG8gaW5jcmVhc2UgaW4gTmV3IFlvcmsgYW5kIExvcyBBbmdlbGVzIHNpbmNlIDIwMTkgYW5kIG5vdCBzdGljayB0byB3aW50ZXIgc2Vhc29uOw0KRm9nIGlzIG1vc3RseSBpbiBMb3MgQW5nZWxlcyBhbmQgYWxzbyBpbmNyZWFzaW5nIHNpbmNlIDIwMTksIA0KUmFpbiBpcyBwcmVzZW50IGlzIGFsbCBjaXRpZXMgYWxsIHRoZSB5ZWFyLCBTZWF0dGxlIHNlZW1zIHRvIGhhdmUgd2F2ZXMgLyBzZWFzb25zIG9mIFJhaW4sIGFuZCBMb3MgQW5nZWxlcyBoYXN0IG1vc3QgeWVhciBhbG1vc3Qgbm8gUmFpbiB3aXRoIHNwaWtlcywgDQpmdW5ueSBpcyB0aGF0IGluIG92ZXJhbGwgcGxvdCBwZXIgY2l0eSB0aGUgc25vdyBzZWFzb25zIGluIE5ldyBZb3JrIGRpZCBub3QgcmVhbGx5IHNob3csIGJ1dCBpbiBTZWF0dGxlIHRoZXkgcmVhbGx5IGRvLCBtYXliZSBzaW5jZSB0aGV5IHN5bmMgd2l0aCByYWluIHdhdmVzDQoNCmBgYHtyfQ0KdGltZV90eXBlX3Bsb3RfcG9pbnQgPC0gd2VhdGhlciAlPiUNCiAgZmlsdGVyKGFzLm51bWVyaWMoRHVyYXRpb24pIDwgNjAwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gU3RhcnRUaW1lLCB5ID0gZmN0X2luZnJlcShUeXBlKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMiwgc2l6ZSA9IDAuNSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgIyBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgU3RhcnRUaW1lIikNCg0KZ2dwbG90bHkodGltZV90eXBlX3Bsb3RfcG9pbnQpDQpgYGANCmBgYHtyfQ0KdGltZV90eXBlX3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBTdGFydFRpbWUsIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9mcmVxcG9seShhbHBoYSA9IDAuOCwgYmlucyA9IDMwKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoZmN0X2luZnJlcShUeXBlKSkpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgU3RhcnRUaW1lIikNCg0KZ2dwbG90bHkodGltZV90eXBlX3Bsb3RfZnJlcSkNCmBgYA0KDQotLS0NCm11bHRpdmFyaWF0ZSBTZXZlcml0eSBvdmVyIFN0YXJ0VGltZQ0KLS0tDQpTZXZlcmUgZXZlbnRzIHNlZW0gdG8gaW5jcmVhc2Ugc2luY2UgMjAxOSwgd2hpY2ggbWlnaHQgYmUgRm9nIGluIExvcyBBbmdlbGVzDQoNCmBgYHtyfQ0KdGltZV9zZXZlcml0eV9wbG90X3BvaW50IDwtIHdlYXRoZXIgJT4lDQogIGZpbHRlcihhcy5udW1lcmljKER1cmF0aW9uKSA8IDYwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IFN0YXJ0VGltZSwgeSA9IGZjdF9pbmZyZXEoU2V2ZXJpdHkpLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICAjIGZhY2V0X2dyaWQodmFycyhDaXR5KSkgKw0KICAgIGdndGl0bGUoIlNldmVyaXR5IG92ZXIgU3RhcnRUaW1lIikNCg0KZ2dwbG90bHkodGltZV9zZXZlcml0eV9wbG90X3BvaW50KQ0KYGBgDQpgYGB7cn0NCnRpbWVfc2V2ZXJpdHlfcGxvdF9mcmVxIDwtIHdlYXRoZXIgJT4lDQogIGZpbHRlcihhcy5udW1lcmljKER1cmF0aW9uKSA8IDYwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IFN0YXJ0VGltZSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ZyZXFwb2x5KGFscGhhID0gMC44LCBiaW5zID0gMzApICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGZhY2V0X2dyaWQodmFycyhmY3RfaW5mcmVxKFNldmVyaXR5KSkpICsNCiAgICBnZ3RpdGxlKCJTZXZlcml0eSBvdmVyIFN0YXJ0VGltZSIpDQoNCmdncGxvdGx5KHRpbWVfc2V2ZXJpdHlfcGxvdF9mcmVxKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIER1cmF0aW9uIG92ZXIgTWludXRlDQotLS0NCmNhbid0IHF1aXRlIGZpbmQgdGhlIHJlYXNvbiB3aHkgdGhlcmUgaXMgc28gbXVjaCByZXBvcnRpbmcgYXQgc3BlY2lmaWMgZml4ZWQgbWludXRlcywgbWlnaHQgYmUgYXV0b21hdGVkIGJ1dCB0cmlnZ2VyIGlzIHVua25vd24sIA0KYnV0IHRoZXJlIGlzIGFuIGludGVyZXN0aW5nIHBhdHRlcm4gaGVyZSwgbWlnaHQgYmUgYmVjYXVzZSBvZiByZWNvcmRpbmcgbWV0aG9kDQoNCmBgYHtyfQ0KbWludXRlX3NldmVyaXR5X3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBmaWx0ZXIoYXMubnVtZXJpYyhEdXJhdGlvbikgPCA2MDApICU+JQ0KICBtdXRhdGUobWludXRlID0gbWludXRlKFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtaW51dGUsIHkgPSBhcy5udW1lcmljKER1cmF0aW9uKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMiwgc2l6ZSA9IDAuNSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiU2V2ZXJpdHkgb3ZlciBNaW51dGUiKQ0KDQpnZ3Bsb3RseShtaW51dGVfc2V2ZXJpdHlfcGxvdF9mcmVxKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIFR5cGUgb3ZlciBNb250aA0KLS0tDQpIb3VzdG9uIGhhcyBjb25zdGFudCBSYWluIGFuZCBsZXNzIEZvZyBpbiBTdW1tZXI7IExvcyBBbmdlbGVzIGhhcyBubyBSYWluIGluIFN1bW1lciwgYnV0IGNvbnN0YW50IEZvZyBhbmQgYWxzbyBDb2xkOyBOZXcgWW9yayBoYXMgY29uc3RhbnQgUmFpbiBhbmQgRm9nLCBTbm93IGluIFdpbnRlciwgQ29sZCBhbHNvIGFsbCBZZWFyOyBTZWF0dGxlIGhhcyBsZXNzIFJhaW4gaW4gU3VtbWVyLCBGb2cgYW5kIFNub3cgaW4gV2ludGVyDQoNCi0+IEkgZ3Vlc3MgdGhlcmUgaXMgYSBiZXR0ZXIgcGxvdCBmb3IgdGhpcywgYnV0IGl0cyBnb29kIGZvciBub3cNCg0KYGBge3J9DQptb250aF90eXBlX3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUobW9udGggPSBtb250aChTdGFydFRpbWUsIGxhYmVsID0gVFJVRSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBtb250aCwgeSA9IGZjdF9pbmZyZXEoVHlwZSksIGNvbCA9IGZjdF9pbmZyZXEoQ2l0eSkpKSArDQogICAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjIsIHNpemUgPSAwLjUpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBNb250aCIpDQoNCmdncGxvdGx5KG1vbnRoX3R5cGVfcGxvdF9mcmVxKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIFR5cGUgb3ZlciBIb3VyDQotLS0NCkZvZyBzZWVtcyB0byBoYXZlIHN0YXJ0aW5nIGhvdXJzIChhbmQgZW5kKTogSG91c3RvbiA5IC0gMTIgdG8gMTMgLSAxNCwgTG9zIEFuZ2VsZXMgMTQgLSAxNiB0byAxNSAtIDE5LCBOZXcgWW9yayAxMiAtIDE0IHRvIDE0IC0gMTYsIFNlYXR0bGUgMTMgLSAxNiB0byAxNSAtIDE4DQpSYWluIGluIEhvdXN0b24gaXMgYWxzbyBtb3JlIG9mdGVuIHN0YXJ0aW5nIGluIHRoZSBzZWNvbmQgaGFsZiBvZiB0aGUgZGF5DQphbGwgb3RoZXJzIGFyZSBjb25zdGFudCBhY3Jvc3MgaG91cnMgb2YgZGF5DQoNCi0+IHN5bmMgZm9yIGxvY2FsIHRpbWUgem9uZSB0byB1bmRlcnN0YW5kIG1vcm5pbmcgYW5kIGV2ZW5pbmcgdGltZSBkZXBlbmRlbmQgZXZlbnRzDQoNCmBgYHtyfQ0KaG91cl90eXBlX3Bsb3RfZnJlcSA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUoaG91ciA9IGhvdXIoU3RhcnRUaW1lKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGhvdXIsIHkgPSBmY3RfaW5mcmVxKFR5cGUpLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgZmFjZXRfZ3JpZCh2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgSG91ciIpDQoNCmhvdXJfdHlwZV9wbG90X2JhciA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUoaG91ciA9IGhvdXIoU3RhcnRUaW1lKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGhvdXIsIGZpbGwgPSBmY3RfaW5mcmVxKFR5cGUpKSkgKw0KICAgICAgIGdlb21fYmFyKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UocHJlc2VydmUgPSAic2luZ2xlIikpICsNCiAgICBmYWNldF9ncmlkKHZhcnMoQ2l0eSkpICsNCiAgICB0aGVtZV9taW5pbWFsKCkgKw0KICAgIGdndGl0bGUoIlR5cGUgb3ZlciBTdGFydCBIb3VyIikNCg0KZ2dwbG90bHkoaG91cl90eXBlX3Bsb3RfZnJlcSkNCmdncGxvdGx5KGhvdXJfdHlwZV9wbG90X2JhcikNCmBgYA0KYGBge3J9DQpob3VyX3R5cGVfcGxvdF9mcmVxIDwtIHdlYXRoZXIgJT4lDQogIG11dGF0ZShob3VyID0gaG91cihFbmRUaW1lKSkgJT4lDQogIGdncGxvdChhZXMoeCA9IGhvdXIsIHkgPSBmY3RfaW5mcmVxKFR5cGUpLCBjb2wgPSBmY3RfaW5mcmVxKENpdHkpKSkgKw0KICAgIGdlb21faml0dGVyKGFscGhhID0gMC4yLCBzaXplID0gMC41KSArDQogICAgZmFjZXRfZ3JpZCh2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgSG91ciIpDQoNCmhvdXJfdHlwZV9wbG90X2JhciA8LSB3ZWF0aGVyICU+JQ0KICBtdXRhdGUoaG91ciA9IGhvdXIoRW5kVGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBob3VyLCBmaWxsID0gZmN0X2luZnJlcShUeXBlKSkpICsNCiAgICAgICBnZW9tX2Jhcihwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHByZXNlcnZlID0gInNpbmdsZSIpKSArDQogICAgZmFjZXRfZ3JpZCh2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgRW5kIEhvdXIiKQ0KDQpnZ3Bsb3RseShob3VyX3R5cGVfcGxvdF9mcmVxKQ0KZ2dwbG90bHkoaG91cl90eXBlX3Bsb3RfYmFyKQ0KYGBgDQoNCi0tLQ0KbXVsdGl2YXJpYXRlIFR5cGUgb3ZlciBZZWFyDQotLS0NCkhvdXN0b24gc3RhYmxlIG92ZXIgeWVhcnMsIExvcyBBbmdlbGVzIGluY3JlYXNlZCBDb2xkIGFuZCBGb2csIE5ldyBZb3JrIG1vc3RseSBzdGFibGUsIGJ1dCBqdW1wIDIwMTkgaW4gQ29sZCwgU2VhdHRsZSBsaXR0bGUgaW5jcmVhc2UgaW4gRm9nIGFuZCBkZWNyZWFzZSBpbiBTbm93IA0KDQpgYGB7cn0NCnllYXJfdHlwZV9wbG90X2ZyZXEgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKHllYXIgPSB5ZWFyKFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCB5ID0gZmN0X2luZnJlcShUeXBlKSwgY29sID0gZmN0X2luZnJlcShDaXR5KSkpICsNCiAgICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuMiwgc2l6ZSA9IDAuNSkgKw0KICAgIGZhY2V0X2dyaWQodmFycyhDaXR5KSkgKw0KICAgIHRoZW1lX21pbmltYWwoKSArDQogICAgZ2d0aXRsZSgiVHlwZSBvdmVyIFllYXIiKQ0KDQpnZ3Bsb3RseSh5ZWFyX3R5cGVfcGxvdF9mcmVxKQ0KYGBgDQpgYGB7cn0NCnllYXJfdHlwZV9wbG90X2ZyZXEgPC0gd2VhdGhlciAlPiUNCiAgbXV0YXRlKHllYXIgPSB5ZWFyKFN0YXJ0VGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSB5ZWFyLCBmaWxsID0gZmN0X2luZnJlcShUeXBlKSkpICsNCiAgICBnZW9tX2Jhcihwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHByZXNlcnZlID0gInNpbmdsZSIpKSArDQogICAgZmFjZXRfZ3JpZCh2YXJzKENpdHkpKSArDQogICAgdGhlbWVfbWluaW1hbCgpICsNCiAgICBnZ3RpdGxlKCJUeXBlIG92ZXIgWWVhciIpDQoNCmdncGxvdGx5KHllYXJfdHlwZV9wbG90X2ZyZXEpDQpgYGANCg0KDQoNCg==